package com.bigfans.systemservice.api;

import com.bigfans.Constants;
import com.bigfans.framework.CurrentUser;
import com.bigfans.framework.CurrentUserFactory;
import com.bigfans.framework.exception.UserExistsException;
import com.bigfans.framework.exception.UserUnAuthorizedException;
import com.bigfans.framework.utils.JsonUtils;
import com.bigfans.framework.utils.JwtUtils;
import com.bigfans.framework.web.BaseController;
import com.bigfans.framework.web.RequestHolder;
import com.bigfans.framework.web.RestResponse;
import com.bigfans.systemservice.model.Operator;
import com.bigfans.systemservice.model.Role;
import com.bigfans.systemservice.service.OperatorService;
import com.bigfans.systemservice.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
public class OperatorApi extends BaseController{

    @Autowired
    private OperatorService operatorService;
    @Autowired
    private RoleService roleService;

    /**
     * 执行登录请求
     *
     * @param operator
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public RestResponse login(@RequestBody Operator operator) throws Exception {
        Operator loginUser = operatorService.login(operator.getUsername(), operator.getPassword());
        if (loginUser == null) {
            throw new UserUnAuthorizedException();
        }
        List<Role> myRoles = roleService.listRolesByUser(loginUser.getId());
        CurrentUser currentUser = this.createSessionUser(operator , myRoles);
        String token = this.generateToken(JsonUtils.toJsonString(currentUser));
        Map<String , Object> data = new HashMap<>();
        data.put("account" , currentUser.getAccount());
        data.put("token" , token);
        data.put("tokenPeriod" , 60 * 60 * 24 * 7); // 保存7天
        return RestResponse.ok(data);
    }

    /**
     * 执行退出请求
     * 客户端清除token即可
     * @return RestResponse
     */
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public RestResponse logout() {
//        getRequest().getSession().invalidate();
//        Cookie userCookie = CookieHolder.get(Constants.TOKEN.HEADER_KEY_NAME);
//        if(userCookie != null){
//            userCookie.setMaxAge(0);
//            userCookie.setPath("/");
//        }
        return RestResponse.ok();
    }

    /**
     * 执行注册请求
     *
     * @param operatorExample
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public RestResponse register(Operator operatorExample) throws Exception {
        boolean passed = true;
        // 判断用户是否存在
        if (operatorService.accountExist(operatorExample.getUsername())) {
            throw new UserExistsException();
        }
        Operator user = operatorService.register(operatorExample);
        List<Role> myRoles = roleService.listRolesByUser(user.getId());
        CurrentUser currentUser = this.createSessionUser(user , myRoles);
        String token = this.generateToken(JsonUtils.toJsonString(currentUser));
        Map<String , Object> data = new HashMap<>();
        data.put("account" , currentUser.getAccount());
        data.put("token" , token);
        data.put("tokenPeriod" , 60 * 60 * 24 * 7); // 保存7天
        return RestResponse.ok(data);
    }

    private CurrentUser createSessionUser(Operator operator , List<Role> roles){
        CurrentUser currentUser = new CurrentUser();
        currentUser.setAccount(operator.getUsername());
        currentUser.setLoginTime(new Date());
        currentUser.setPeriod(60 * 60 * 24 * 7);
        currentUser.setType(CurrentUser.TYPE.OPERATOR);
        currentUser.setUid(operator.getId());
        currentUser.setRoles(roles.stream().map(Role::getName).collect(Collectors.toList()));
        return currentUser;
    }

    private String generateToken(String tokenStr){
        String jwtTokenStr = JwtUtils.create(tokenStr, Constants.TOKEN.JWT_SECURITY_KEY);
        return jwtTokenStr;
    }
}
